<template>
  <el-dialog :visible.sync="currentVisible"
             append-to-body
             destroy-on-close
             :close-on-click-modal="false"
             :title="title"
             custom-class="authentication-dialog"
             width="552px"
             @close="onClose">
    <div v-loading="loading"
         class="flex flex-col h-full">
      <template v-if="active === 'download'">
        <div class="authentication-dialog__bg"></div>

        <div class="authentication-dialog__desc">
          Instead of waiting for text messages, get verification codes from an
          authenticator app. It works even if your phone is offline.
        </div>

        <div class="authentication-dialog__app">
          First, download 2FA from the

          <el-link type="primary">Google Play Store</el-link>
          or the
          <el-link type="primary">iOS App Store</el-link>
          .
        </div>
      </template>

      <div class="authentication-dialog__qr flex flex-col"
           v-if="active === 'qrcode'">
        <ul class="native">
          <li>In the 2FA app tap the +</li>
          <li>Choose <strong>Scan a QR code</strong></li>
        </ul>

        <div class="authentication-dialog__qr-code center-center">
          <div id="root"
               ref="qrcode"></div>
        </div>

        <el-button type="text"
                   @click="onScan">Can’t scan it?</el-button>
      </div>

      <div class="authentication-dialog__scan"
           v-if="active === 'scan'">
        <ol class="native">
          <li>In the 2FA app tap the + then tap <strong>Enter a setup key</strong></li>
          <li>Enter your email address and this key (spaces don’t matter):
            <br>
            <strong>{{secret}}</strong>
          </li>
          <li>Make sure <strong>Time based</strong> is selected</li>
          <li>Tap <strong>Add</strong> to finish</li>
        </ol>
      </div>

      <div class="authentication-dialog__form"
           v-if="active === 'code'">
        <el-form :model="form"
                 ref="form"
                 :rules="rules">
          <el-form-item prop="code"
                        label="Enter the 6-digit code you see in the app">
            <el-input placeholder="Enter Code"
                      maxlength="6"
                      v-model="form.code"></el-input>
          </el-form-item>
        </el-form>
      </div>

      <div class="flex-1"></div>
      <div class="authentication-dialog__footer flex">
        <el-button type="text"
                   v-if="history.length"
                   @click="onBack">Back</el-button>

        <div class="flex-1 text-right">
          <el-button type="text"
                     @click="onClose">Cancel</el-button>
          <el-button type="primary"
                     size="mini"
                     v-if="active !== 'code'"
                     @click="onNext">Next</el-button>
          <el-button type="primary"
                     v-if="active === 'code'"
                     @click="onVerify"
                     size="mini">Verify</el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script>
import ZIcon from "@/components/storybook/z-icon";
import { fetchCodeUrl, fetch2faVerify, verify2faCode } from '@/api/new'
import QRCode from 'qrcodejs2'
import useErrorMessage from '@/components/storybook/hooks/useErrorMessage'
import { queryToObject } from '@/components/storybook/utilties/tools'

export default {
  name: "AuthenticationModal",
  props: {
    visible: Boolean,
    username: String
  },
  components: {
    ZIcon,
  },
  data () {
    return {
      active: 'qrcode',
      history: [],
      loading: false,
      qrcode: null,
      form: {
        haloUrl: null,
        code: null,
        username: this.username || this.$store.state.user.username
      },
      rules: {
        code: [
          {
            required: true,
            message: 'Please enter your verification code.',
            trigger: 'change'
          },
          { min: 6, max: 6, message: 'Please enter the 6-digit code', trigger: 'change' }
        ],
      }
    };
  },
  computed: {
    currentVisible: {
      get () {
        return this.visible;
      },
      set (val) {
        this.$emit("update:visible", val);
      },
    },
    title () {
      return "Set Up Authenticaion";
    },
    secret () {
      const [_, url] = (this.form.haloUrl || '').split('?')
      const { secret = '' } = queryToObject(url)

      return secret.replace(/(.{4})/g, '$&  ')
    }
  },
  created () {
    this.init()
  },
  methods: {

    async init () {
      try {
        this.loading = true

        const code = await this.get2faVerify()

        if (code === 2) {
          this.active = 'code'
          return
        }

        this.form.haloUrl = await this.get2faCode()

        this.active = 'qrcode'

        this.$nextTick(() => {
          this.qrcode = new QRCode(this.$refs.qrcode, {
            text: this.form.haloUrl,
            width: 140,
            height: 140,
            colorDark: "#000000",
            colorLight: "#ffffff",
            correctLevel: QRCode.CorrectLevel.H
          });
        })
      } catch (error) {

      } finally {
        this.loading = false
      }
    },
    async get2faVerify () {

      const params = {
        username: this.form.username
      }
      const { data: response } = await fetch2faVerify(params)

      if (response.code !== 0) {
        throw response.msg
      }

      return response.data ?? 2
    },
    async get2faCode () {

      const params = {
        username: this.form.username
      }
      const { data: response } = await fetchCodeUrl(params)

      if (response.code !== 0) {
        throw response.msg
      }

      return response.data
    },
    async onVerify () {
      try {
        this.loading = true

        await this.$refs['form'].validate()

        const params = {
          ...this.form,

        }
        const { data: response } = await verify2faCode(params)
        if (response.code !== 0 || !response.data) {
          this.$refs['form'].fields[0].validateMessage = 'Verification failed. Please try again.'
          this.$refs['form'].fields[0].validateState = 'error'

          return
        }

        if (response.data) {
          this.$message.success("Success")
          this.$emit('success')
          this.currentVisible = false
        }
      } catch (error) {
        useErrorMessage(error)
      } finally {
        this.loading = false

      }
    },
    onClose () {
      this.currentVisible = false
      this.qrcode && this.qrcode.clear()
      this.$emit('close')
    },
    onScan () {
      this.active = 'scan'
      this.history.push('qrcode')

    },
    onBack () {
      this.history.pop();
      this.active = this.history.length ? this.history[this.history.length - 1] : 'qrcode'

      if (this.active === 'qrcode') {
        this.$nextTick(() => {
          this.qrcode = new QRCode(this.$refs.qrcode, {
            text: this.form.haloUrl,
            width: 140,
            height: 140,
            colorDark: "#000000",
            colorLight: "#ffffff",
            correctLevel: QRCode.CorrectLevel.H
          });

        })
      }

      this.form.code = null
    },
    onNext () {
      if (this.active === 'qrcode') {
        this.active = 'code'
      }
      if (this.active === 'scan') {
        this.active = 'code'
      }
      this.history.push(this.active)
      this.form.code = null
    }
  }
};
</script>

<style lang="scss">
.authentication-dialog {
  &__bg {
    background: url("../../../../../assets/img/authentication.png") no-repeat;
    background-size: 100% 100%;
    height: 184px;
  }
  &__desc,
  &__app {
    font-size: 14px;
    font-weight: 400;
    color: #8d8d8d;
    line-height: 20px;
  }
  &__desc {
    margin-top: 16px;
  }
  &__app {
    margin-top: 30px;
  }
  &__action {
    margin-top: 16px;
    .el-button {
      border-color: #17b3a3;
      color: #17b3a3;
    }
  }

  &__qr {
    .native {
      list-style: initial;
      padding-left: 18px;
      line-height: 20px;
      li {
        list-style: initial;
      }
    }

    &-code {
      margin: 36px 0 28px;
      #root {
        width: 144px;
        height: 144px;
      }
    }
  }
  &__scan {
    .native {
      list-style: initial;
      padding-left: 18px;
      line-height: 20px;
      li {
        list-style: initial;
        list-style-type: decimal;
      }
    }
  }

  &__card {
    margin-top: 16px;
    height: 140px;
    border-radius: 4px 4px 4px 4px;
    border: 1px solid #dde1e6;
    padding: 16px;
    &-header {
      font-weight: 600;
      color: #8d8d8d;
      line-height: 16px;
      font-size: 12px;
    }
    &-content {
      img {
        margin-right: 16px;
      }
      &__wrapper {
        span:nth-of-type(1) {
          font-size: 14px;
          font-weight: 600;
          color: #262626;
          line-height: 20px;
        }
        span:nth-of-type(2) {
          font-size: 12px;
          font-weight: 400;
          color: #8d8d8d;
          line-height: 16px;
        }
      }
    }
    &-action {
      .el-button {
        padding: 0;
      }
    }
  }

  &__form {
    margin-top: 12px;
  }

  &__footer {
    margin-top: 12px;
    .el-button--text {
      color: #262626;
    }
  }
  .el-dialog__body {
    height: 428px;
  }
}
</style>
